package com.martin.dms.dataservices.hib;

import java.util.List;

import org.hibernate.Session;

import com.martin.dms.dataservices.CategoryDataService;
import com.martin.dms.model.Category;
import com.martin.dms.model.hib.CategoryHib;
import com.martin.dms.model.hib.ItemHib;

/**
 * Hibernate implementation of the Category data service.
 * 
 * @author mtsvetkov
 */
public class CategoryDataServiceHib implements CategoryDataService {

    private static final String CATEGORY_GET_ALL_QUERY = "Category.getAll";
    
    private Session session;

    /**
     * Constructor that expects a hibernate session.
     * 
     * @param session - the current hibernate session.
     */
    public CategoryDataServiceHib(Session session) {
        this.session = session;
    }

    /**
     * {@inheritDoc}
     */
    public void addItem(long categoryId, long itemId) {
        CategoryHib category = get(categoryId);
        addItem(category, itemId);
    }

    /**
     * {@inheritDoc}
     */
    public void addItems(long categoryId, List<Long> itemIds) {
        CategoryHib category = get(categoryId);
        for (Long itemId : itemIds) {
            addItem(category, itemId);
        }
    }

    /**
     * {@inheritDoc}
     */
    public Category create(Category category) {
        CategoryHib result = new CategoryHib();
        result.setName(category.getName());
        session.save(result);
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public CategoryHib get(long categoryId) {
        return (CategoryHib) session.get(CategoryHib.class, Long.valueOf(categoryId));
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public List<Category> getAll() {
        return session.getNamedQuery(CATEGORY_GET_ALL_QUERY).list();
    }

    /**
     * {@inheritDoc}
     */
    public void delete(long categoryId) {
        CategoryHib category = get(categoryId);
        session.delete(category);
    }

    /**
     * {@inheritDoc}
     */
    public void removeItem(long categoryId, long itemId) {
        CategoryHib category = get(categoryId);
        removeItem(category, itemId);
    }

    /**
     * {@inheritDoc}
     */
    public void removeItems(long categoryId, List<Long> itemIds) {
        CategoryHib category = get(categoryId);
        for (Long itemId : itemIds) {
            removeItem(category, itemId);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void updateName(long categoryId, String name) {
        CategoryHib category = get(categoryId);
        category.setName(name);
    }

    private void removeItem(CategoryHib category, long itemId) {
        ItemHib item = getItem(itemId);
        category.removeItem(item);
    }

    private void addItem(CategoryHib category, long itemId) {
        ItemHib item = getItem(itemId);
        category.addItem(item);
    }

    private ItemHib getItem(long itemId) {
        return (ItemHib) session.get(ItemHib.class, Long.valueOf(itemId));
    }

}
